<template>
  <div class="captcha-container">
    <a-input
      v-model:value="inputValue"
      placeholder="请输入验证码"
      size="large"
      @input="handleInput"
      @pressEnter="$emit('verify', inputValue)"
      class="captcha-input"
    >
      <template #prefix>
        <SafetyOutlined class="input-icon" />
      </template>
    </a-input>

    <div class="captcha-display" @click="refreshCaptcha">
      <canvas
        ref="canvasRef"
        :width="captchaWidth"
        :height="captchaHeight"
        class="captcha-canvas"
      ></canvas>
      <div class="refresh-hint">点击刷新</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { SafetyOutlined } from '@ant-design/icons-vue'

interface Props {
  modelValue?: string
}

interface Emits {
  (e: 'update:modelValue', value: string): void
  (e: 'verify', code: string): void
  (e: 'refresh', code: string): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const canvasRef = ref<HTMLCanvasElement>()
const inputValue = ref('')
const captchaCode = ref('')
const captchaWidth = 120
const captchaHeight = 40

// 生成随机字符
const generateRandomChar = () => {
  const chars = 'ABCDEFGHJKMNPQRSTUVWXYZabcdefhijkmnpqrstuvwxyz23456789'
  return chars.charAt(Math.floor(Math.random() * chars.length))
}

// 生成验证码
const generateCaptcha = () => {
  let code = ''
  for (let i = 0; i < 4; i++) {
    code += generateRandomChar()
  }
  captchaCode.value = code
  drawCaptcha()
  emit('refresh', code)
}

// 绘制验证码
const drawCaptcha = () => {
  const canvas = canvasRef.value
  if (!canvas) return

  const ctx = canvas.getContext('2d')
  if (!ctx) return

  // 清空画布
  ctx.clearRect(0, 0, captchaWidth, captchaHeight)

  // 设置背景渐变
  const gradient = ctx.createLinearGradient(0, 0, captchaWidth, captchaHeight)
  gradient.addColorStop(0, 'rgba(15, 23, 42, 0.8)')
  gradient.addColorStop(0.5, 'rgba(30, 41, 59, 0.8)')
  gradient.addColorStop(1, 'rgba(51, 65, 85, 0.8)')
  ctx.fillStyle = gradient
  ctx.fillRect(0, 0, captchaWidth, captchaHeight)

  // 绘制干扰线
  for (let i = 0; i < 5; i++) {
    ctx.strokeStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 0.3)`
    ctx.lineWidth = 1
    ctx.beginPath()
    ctx.moveTo(Math.random() * captchaWidth, Math.random() * captchaHeight)
    ctx.lineTo(Math.random() * captchaWidth, Math.random() * captchaHeight)
    ctx.stroke()
  }

  // 绘制验证码文字
  const colors = ['#00ffff', '#8a2be2', '#00ff7f', '#ff6b6b', '#ffd93d']
  for (let i = 0; i < captchaCode.value.length; i++) {
    ctx.font = `bold ${20 + Math.random() * 4}px Arial`
    ctx.fillStyle = colors[Math.floor(Math.random() * colors.length)]
    ctx.textBaseline = 'middle'

    const x = 15 + i * 22 + Math.random() * 8
    const y = captchaHeight / 2 + Math.random() * 6 - 3
    const angle = (Math.random() - 0.5) * 0.4

    ctx.save()
    ctx.translate(x, y)
    ctx.rotate(angle)
    ctx.fillText(captchaCode.value[i], 0, 0)
    ctx.restore()
  }

  // 绘制干扰点
  for (let i = 0; i < 30; i++) {
    ctx.fillStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}, 0.4)`
    ctx.beginPath()
    ctx.arc(
      Math.random() * captchaWidth,
      Math.random() * captchaHeight,
      Math.random() * 2,
      0,
      2 * Math.PI
    )
    ctx.fill()
  }
}

// 刷新验证码
const refreshCaptcha = () => {
  generateCaptcha()
}

// 处理输入
const handleInput = (e: Event) => {
  const value = (e.target as HTMLInputElement).value
  emit('update:modelValue', value)
}

// 验证验证码
const verifyCaptcha = (input: string) => {
  return input.toLowerCase() === captchaCode.value.toLowerCase()
}

// 监听props变化
watch(() => props.modelValue, (newValue) => {
  inputValue.value = newValue || ''
})

// 暴露验证方法
defineExpose({
  verifyCaptcha,
  refreshCaptcha,
  captchaCode: captchaCode.value
})

onMounted(() => {
  generateCaptcha()
})
</script>

<style scoped>
.captcha-container {
  display: flex;
  gap: 12px;
  align-items: center;
}

.captcha-input {
  flex: 1;
}

.input-icon {
  color: #64748b;
}

:deep(.ant-input-affix-wrapper) {
  background: rgba(15, 23, 42, 0.8) !important;
  border: 1px solid rgba(0, 255, 255, 0.3) !important;
  border-radius: 12px;
  padding: 12px 16px;
  transition: all 0.3s ease;
}

:deep(.ant-input-affix-wrapper:focus-within) {
  border-color: rgba(0, 255, 255, 0.6) !important;
  box-shadow: 0 0 0 2px rgba(0, 255, 255, 0.2) !important;
}

:deep(.ant-input) {
  background: transparent !important;
  border: none !important;
  color: #e2e8f0 !important;
  font-size: 16px;
}

:deep(.ant-input::placeholder) {
  color: #64748b !important;
}

.captcha-display {
  position: relative;
  cursor: pointer;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid rgba(0, 255, 255, 0.3);
  transition: all 0.3s ease;
}

.captcha-display:hover {
  border-color: rgba(0, 255, 255, 0.6);
  box-shadow: 0 0 10px rgba(0, 255, 255, 0.2);
}

.captcha-canvas {
  display: block;
  background: transparent;
}

.refresh-hint {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.7);
  color: #cbd5e1;
  font-size: 10px;
  text-align: center;
  padding: 2px;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.captcha-display:hover .refresh-hint {
  opacity: 1;
}

/* 响应式设计 */
@media (max-width: 480px) {
  .captcha-container {
    flex-direction: column;
    gap: 16px;
  }

  .captcha-display {
    align-self: center;
  }
}
</style>
